package com.it.ems.mapper;

import com.it.ems.entity.Role;
import com.it.ems.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Options;

import java.util.List;

@Mapper
public interface UserMapper {

    @Results(id = "userResultMap", value = {
        @Result(property = "id", column = "id"),
        @Result(property = "username", column = "username"),
        @Result(property = "password", column = "password"),
        @Result(property = "realName", column = "real_name"),
        @Result(property = "phoneNumber", column = "phone_number"),
        @Result(property = "email", column = "email"),
        @Result(property = "avatar", column = "avatar"),
        @Result(property = "createdAt", column = "created_at"),
        @Result(property = "updatedAt", column = "updated_at"),
        @Result(property = "enabled", column = "enabled"),
        @Result(property = "roles", javaType = List.class, column = "id",
                many = @org.apache.ibatis.annotations.Many(select = "com.it.ems.mapper.RoleMapper.findRolesByUserId"))
    })
    @Select("SELECT u.* FROM users u WHERE u.id = #{id}")
    User findById(Long id);
    
    @ResultMap("userResultMap")
    @Select("SELECT u.* FROM users u WHERE u.username = #{username}")
    User findByUsername(String username);
    
    @ResultMap("userResultMap")
    @Select("SELECT u.* FROM users u WHERE u.phone_number = #{phoneNumber}")
    User findByPhone(String phoneNumber);
    
    @Insert("INSERT INTO users (username, password, real_name, phone_number, email, created_at) " +
            "VALUES (#{username}, #{password}, #{realName}, #{phoneNumber}, #{email}, NOW())")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(User user);
    
    @Update("UPDATE users SET " +
            "username = #{username}, " +
            "real_name = #{realName}, " +
            "phone_number = #{phoneNumber}, " +
            "email = #{email}, " +
            "updated_at = NOW() " +
            "WHERE id = #{id}")
    int update(User user);

    @Update("UPDATE users SET " +
            "username = #{username}, " +
            "real_name = #{realName}, " +
            "phone_number = #{phoneNumber}, " +
            "updated_at = NOW() " +
            "WHERE id = #{id}")
    int updateProfile(User user);

    @Update("UPDATE users SET password = #{password}, updated_at = NOW() WHERE id = #{id}")
    int updatePassword(@Param("id") Long id, @Param("password") String password);

    @ResultMap("userResultMap")
    @Select("SELECT u.* FROM users u")
    List<User> findAll();

    @Update("UPDATE user_roles SET role_id = (SELECT id FROM roles WHERE name = #{newRole}) WHERE user_id = #{userId}")
    void updateUserRole(@Param("userId") Long userId, @Param("newRole") String newRole);

    @Delete("DELETE FROM users WHERE id = #{id}")
    void delete(Long id);

    @ResultMap("userResultMap")
    @Select("SELECT DISTINCT u.* FROM users u " +
            "JOIN user_roles ur ON u.id = ur.user_id " +
            "JOIN roles r ON ur.role_id = r.id " +
            "WHERE r.name = #{roleName} AND u.deleted = 0 AND u.id != #{currentUserId}")
    List<User> findByRole(@Param("roleName") String roleName, @Param("currentUserId") Long currentUserId);
} 